package com.repair.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.repair.config.RedisKey;
import com.repair.dao.RepairStoreMapper;
import com.repair.dto.RepairStoreDto;
import com.repair.entity.RepairStore;
import com.repair.exception.RepairStoreException;
import com.repair.param.RepairStoreAddParam;
import com.repair.param.RepairStoreFindParam;
import com.repair.param.RepairStoreStateParam;
import com.repair.param.RepairStoreUpdateParam;
import com.repair.service.RepairStoreService;
import com.repair.util.PageInfo;
import com.repair.util.StateDate;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 维修材料库存表 服务实现类
 * </p>
 *
 * @author 小叶
 * @since 2024年04月03日
 */
@Service
public class RepairStoreServiceImpl extends ServiceImpl<RepairStoreMapper, RepairStore> implements RepairStoreService {
    @Autowired
    private RepairStoreMapper repairStoreMapper;
    @Autowired
    private RedissonClient redissonClient;

    @Override
    public RepairStore add(RepairStoreAddParam param) {
        //材料编码不能相同
        RepairStore code = repairStoreMapper.selectOne(new QueryWrapper<RepairStore>().eq("material_code", param.getMaterialCode()));
        if (code!=null) throw new RepairStoreException(500,"材料编码已存在");
        //材料名称如果相同，规格型号不能相同
        QueryWrapper<RepairStore> wrapper = new QueryWrapper<RepairStore>().eq("material_name", param.getMaterialName()).eq("material_style", param.getMaterialStyle());
        if (repairStoreMapper.selectCount(wrapper)>0){
            throw new RepairStoreException(500,"材料名称规格型号已存在");
        }
        //可以进行新增
        RepairStore repairStore = BeanUtil.toBean(param, RepairStore.class);
        repairStore.setMaterialState(StateDate.MATERIAL_STATE_UP);
        repairStoreMapper.insert(repairStore);
        return repairStore;
    }

    @Override
    public RepairStore updateRepairStore(RepairStoreUpdateParam param) throws InterruptedException {
        //判断要修改的材料是否存在
        RepairStore repairStore = repairStoreMapper.selectById(param.getId());
        if (repairStore==null) throw new RepairStoreException(500,"材料不存在");
        //修改库存量时要进行加锁操作
        RLock lock = redissonClient.getFairLock(RedisKey.lockRepairStoreNum(param.getId() + ""));
        RLock multiLock = redissonClient.getMultiLock(lock);
        multiLock.tryLock(10, TimeUnit.SECONDS);
        try {
            //修改材料的库存
            repairStore.setMaterialNum(param.getMaterialNum());
        }catch (Exception e){
            throw e;
        }finally {
            multiLock.unlock();
        }
        //修改其他信息
        repairStore.setRemarks(param.getRemarks());
        repairStoreMapper.updateById(repairStore);
        return repairStore;
    }

    @Override
    public RepairStore changeState(RepairStoreStateParam param) {
        //修改的维修材料要存在
        RepairStore repairStore = repairStoreMapper.selectById(param.getId());
        if (repairStore==null) throw new RepairStoreException(500,"要修改的维修材料不存在");
        //传入的状态数值只能是0,1,2中的一个
        if (param.getMaterialState()!=0&&param.getMaterialState()!=1&&param.getMaterialState()!=2){
            throw new RepairStoreException(500,"状态值错误");
        }
        //维修材料被删除后不能上下架
        if (repairStore.getMaterialState()== StateDate.MATERIAL_STATE_DELETE){
            if (param.getMaterialState()==StateDate.MATERIAL_STATE_UP|| param.getMaterialState()==StateDate.MATERIAL_STATE_DOWN){
                throw new RepairStoreException(500,"该材料已被删除，不能进行上架或下架");
            }
        }
        repairStore.setMaterialState(param.getMaterialState());
        repairStoreMapper.updateById(repairStore);
        return repairStore;
    }

    @Override
    public RepairStore findById(Integer id) {
        RepairStore repairStore = repairStoreMapper.selectById(id);
        if (repairStore==null) throw new RepairStoreException(500,"材料不存在");
        return repairStore;
    }

    @Override
    public PageInfo<RepairStoreDto> repairFind(RepairStoreFindParam param) {
        //使用分页进行查询
        Page<RepairStore> page = new Page<>(param.getPageNum() == null ? 1 : param.getPageNum(), param.getPageSize() == null ? 5 : param.getPageSize());
        QueryWrapper<RepairStore> wrapper = new QueryWrapper<>();
        //维修员只能查询材料状态上架的材料
        if (param.getIsAdmin()==0){
            wrapper.eq("material_state",StateDate.MATERIAL_STATE_UP);
        }else{
            //管理员不能查询已删除的材料
            wrapper.ne("material_state",StateDate.MATERIAL_STATE_DELETE);
        }
        if (param.getMaterialCode()!=null&&param.getMaterialCode()!=""){
            wrapper.like("material_code",param.getMaterialCode());
        }
        if (param.getMaterialName()!=null&&param.getMaterialName()!=""){
            wrapper.like("material_name",param.getMaterialName());
        }
        if (param.getMaterialStyle()!=null && param.getMaterialStyle()!=""){
            wrapper.like("material_style",param.getMaterialStyle());
        }
        repairStoreMapper.selectPage(page,wrapper);
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        List<RepairStoreDto> dtos = BeanUtil.copyToList(page.getRecords(), RepairStoreDto.class);
        for (RepairStoreDto dto : dtos) {
            dto.setStateName("上架");
        }
        pageInfo.setList(dtos);
        pageInfo.setPages(page.getPages());
        return pageInfo;
    }
}
